using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using Lync.Widget.Library.Presentation.Entities;
using Lync.Widget.Library.Presentation.Models;
using Lync.Widget.Library.Presentation.Views;

namespace Lync.Widget.Library.Presentation.Presenters
{
    public class LanguagePacksPresenter : ILanguagePacksPresenter
    {
        public ILanguagePacksView View { get; set; }
        public ILanguagePacksModel Model { get; set; }

        public LanguagePacksPresenter(ILanguagePacksView view, ILanguagePacksModel model)
        {
            View = view;
            Model = model;
        }

        public void OnLoad()
        {
            View.ShowDownloadButton = true;

            var allPacks = Model.GetAll();

            var allLanguages = allPacks.GroupBy(p => p.Language).Select(p => p.Key).ToList();

            View.SupportedLanguages = allLanguages.Select(l => new Language
                                                                   {
                                                                       Name = l,
                                                                       Value = l
                                                                   }).Cast<ILanguage>().ToList();

            var defaultPack = allPacks.SingleOrDefault(p => p.IsDefault);

            if (defaultPack != null)
            {
                View.Language = View.CurrentLanguage = defaultPack.Language;
                View.IsDefaultLanguage = defaultPack.IsDefault;

                var resources = defaultPack.Resources;

                if (resources != null && resources.Count > 0)
                {
                    View.Resources = resources;
                    View.ShowResults = true;
                    View.ShowSaveButton = true;
                }
                else
                {
                    View.ErrorMessage = "No resources found";
                }
            }
        }

        public bool AddLanguageResource()
        {
            View.Saved = false;

            var newLanguageResource = View.NewLanguageResource;

            var allResources = View.Resources;

            if (allResources.Any(f => f.Name.ToLower() == newLanguageResource.Name.ToLower() && f.Key.ToLower() == newLanguageResource.Key.ToLower()))
            {
                View.ErrorMessage = String.Format("Resource with name '{0}' and key '{1}' already exists", newLanguageResource.Name, newLanguageResource.Key);
                return false;
            }

            View.AddToList(newLanguageResource);
            return true;
        }

        public void UpdateView()
        {
        }

        public bool RemoveLanguageResource(string key, string name)
        {
            View.Saved = false;

            var allResources = View.Resources;
            var resource = allResources.SingleOrDefault(r => r.Key == key && r.Name == name);

            if (resource != null)
            {
                allResources.Remove(resource);
                View.Resources = allResources;
                return true;
            }

            View.ErrorMessage = String.Format("Resource with key '{0}' and name '{1}' was not found", key, name);
            return false;
        }

        public void ChangeLanguage()
        {
            try
            {
                var language = View.Language;
                var currentLanguage = View.CurrentLanguage;

                if (language == currentLanguage)
                    return;

                var pack = Model.Get(language);

                if (pack == null || pack.Resources == null || pack.Resources.Count == 0)
                {
                    pack = Model.GetDefault();
                    View.IsDefaultLanguage = false;
                    View.Resources = pack.Resources.Select(p => new LanguageResource
                    {
                        Name = p.Name,
                        Key = p.Key
                    }).Cast<ILanguageResource>().ToList();
                }
                else
                {
                    View.IsDefaultLanguage = pack.IsDefault;
                    View.Resources = pack.Resources;
                }
                
                View.CurrentLanguage = language;
                View.Saved = false;
            }
            catch (Exception exception)
            {
                View.ErrorMessage = String.Format("{0}", exception.Message);
            }
        }

        public bool Save()
        {
            var resources = View.Resources;
            var language = View.Language;
            var isDefault = View.IsDefaultLanguage;

            try
            {
                if (resources.Count > 0)
                {
                    Model.Save(language, resources, isDefault);
                }

                View.Saved = true;
                return true;
            }
            catch (Exception exception)
            {
                View.ErrorMessage = exception.Message;
            }
            return false;
        }

        public void DownloadResourceFile(HttpContext context)
        {
            try
            {
                var pack = Model.Get(View.CurrentLanguage);

                var sb = new StringBuilder();

                var resourcesGrouped = pack.Resources.GroupBy(r => r.Name).ToList().Select(g => new { g.Key, Resources = g }).ToList();

                foreach (var resourceGroup in resourcesGrouped)
                {
                    sb.AppendLine(String.Format("{0} = {{", resourceGroup.Key));

                    var counter = 0;
                    var resourceCount = resourceGroup.Resources.Count();
                    foreach (var resource in resourceGroup.Resources)
                    {
                        var comma = (resourceCount > 1 && counter < resourceCount - 1) ? "," : "";
                        sb.AppendLine(String.Format("   {0}: \"{1}\"{2}", resource.Key, resource.Value, comma));
                        counter++;
                    }

                    sb.AppendLine(String.Format("}};"));
                    sb.AppendLine();
                }

                var bytes = Encoding.UTF8.GetBytes(sb.ToString());

                context.Response.Clear();
                context.Response.ContentType = "text/xml";
                context.Response.AddHeader("content-disposition", String.Format("attachment;filename=widget-{0}.js", pack.Language.ToLower()));
                context.Response.Buffer = true;
                context.Response.OutputStream.Write(bytes, 0, bytes.Length);
                context.Response.End();
            }
            catch (Exception exception)
            {
                View.ErrorMessage = String.Format("Error downloading resource : {0}", exception.Message);
            }

        }
        public void AddLanguage()
        {
            try
            {
                var newLanguageCode = View.NewLanguage;

                if (!String.IsNullOrEmpty(newLanguageCode))
                {
                    var languages = View.SupportedLanguages;

                    if (languages.Any(l => l.Value == newLanguageCode))
                    {
                        throw new Exception("Language already exists");
                    }

                    var newLanguage = new Language
                                          {
                                              Name = newLanguageCode,
                                              Value = newLanguageCode,
                                          };

                    languages.Add(newLanguage);
                    View.SupportedLanguages = languages;
                    View.Language = newLanguage.Value;
                    ChangeLanguage();
                }
            }
            catch (Exception exception)
            {
                View.ErrorMessage = String.Format("Error adding language : {0}", exception.Message);
            }
        }
    }
}